﻿using blackhouse.IdentityCms.Business.Observables;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Policy;
using System.Text;
using blackhouse.IdentityCms.Data;

namespace blackhouse.IdentityCms.Business.Sites {
    public class CmsSiteLanguage {

        #region Fields

        private readonly int siteId;
        private readonly ISiteDbContext dbContext;
        private readonly List<CultureInfo> languages;

        #endregion

        #region Properties

        public CultureInfo DefaultLanguage {
            get;
            private set;
        }

        public bool SupportLanguages {
            get { return this.languages.Count > 1; }
        }

        public bool AllowUseShorterName {
            get {
                var q = from cp in this.languages
                        group cp by cp.Parent.Name
                            into prns
                            select prns.Count();
                return !q.Any(i => i > 1);
            }
        }

        #endregion

        #region Events

        public static event EventHandler<LanguageEventArgs> LanguageChangeObservable;

        #endregion

        #region Constructors

        public CmsSiteLanguage(int siteId) {
            this.siteId = siteId;
            this.dbContext = DbFactory.GetSiteDbContext();
            IEnumerable<string> data = this.dbContext.GetSiteLanguagesBySiteId(siteId);
            this.languages = data.Select(CultureInfo.GetCultureInfo).ToList();
            this.DefaultLanguage = this.languages.Count > 0 ? this.languages.First() : CultureInfo.InvariantCulture;
        }

        #endregion

        #region Methods

        public void AddLanguage(CultureInfo culture, bool setAsDefault = false) {
            if (this.DefaultLanguage.Equals(CultureInfo.InvariantCulture)) setAsDefault = true;
            if (this.languages.Contains(culture)) {
                if (setAsDefault && !this.DefaultLanguage.Equals(culture)) {
                    this.dbContext.SaveSiteDefaultLanguage(this.siteId, culture.Name);
                    this.DefaultLanguage = culture;
                }
            } else {
                this.languages.Add(culture);
                this.dbContext.AddSiteLanguage(this.siteId, culture.Name);
                if (setAsDefault) {
                    this.DefaultLanguage = culture;
                    this.dbContext.SaveSiteDefaultLanguage(this.siteId, culture.Name);
                }
                if (LanguageChangeObservable != null) {
                    LanguageChangeObservable(this, new LanguageEventArgs(LanguageEventReason.Add, culture, this.siteId));
                }
            }
        }

        public void RemoveLanguage(CultureInfo culture) {
            if (culture.IsNeutralCulture || !this.languages.Contains(culture)) return;
            if (LanguageChangeObservable != null)
                LanguageChangeObservable(this, new LanguageEventArgs(LanguageEventReason.Remove, culture, this.siteId));
            this.languages.Remove(culture);
            this.dbContext.RemoveSiteLanguage(this.siteId, culture.Name);
            if (this.DefaultLanguage.Equals(culture)) {
                this.DefaultLanguage = this.languages.Count > 0 ? this.languages.First() : CultureInfo.InvariantCulture;
            }
        }

        public bool Constains(CultureInfo culture) {
            return this.languages.Contains(culture);
        }

        #endregion

    }
}
